package com.winit.openapi.ece.utils;

import java.math.BigDecimal;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.winit.openapi.constants.ApiConstant;
import com.winit.openapi.constants.ErrorCode;
import com.winit.openapi.ece.vo.EceOrderDispatchType;
import com.winit.openapi.exception.ApiException;
import com.winit.openapi.util.ValidateUtil;

/**
 * ISP Order工具类 包括校验、组装等
 * 
 * @version <pre>
 * Author	Version		Date		Changes
 * bing.gu 	1.0  		2015年5月23日 	Created
 *
 * </pre>
 * @since 1.
 */
public class EceOrderfieldValidator {

    /**
     * 校验批量导入进口订单参数
     * 
     * @param json
     */
    public static void validOrderField(JSONObject json) {
        // paymentTransactionID
        ValidateUtil.validNotNull(json, "paymentTransactionID", "Payment Transaction ID");
        ValidateUtil.validMaxLength(json, "paymentTransactionID", "Payment Transaction ID", 32);
        // inspectionWhName
        ValidateUtil.validNotNull(json, "warehouseName", "Inspection WH");
        ValidateUtil.validMaxLength(json, "warehouseName", "Inspection WH", 60);
        // winitProductCode
        ValidateUtil.validNotNull(json, "winitProductCode", "Winit product");
        ValidateUtil.validMaxLength(json, "winitProductCode", "Winit product", 50);
        // isInsure 是否保险 add by changjun.xiang 2016-4-20
        if (json.containsKey("isInsure")) {
            if ((ApiConstant.SHORT_YES.equalsIgnoreCase(json.getString("isInsure").trim()))
                || (ApiConstant.SHORT_NO.equalsIgnoreCase(json.getString("isInsure").trim()))) {
                ValidateUtil.validNotNull(json, "isInsure", "Is Insure");
                ValidateUtil.validMaxLength(json, "isInsure", "Is Insure", 1);
                //如果下单时卖家选择买保险，则【货款】必填 add by minghao.deng 2016-04-26
                if (ApiConstant.SHORT_YES.equalsIgnoreCase(json.getString("isInsure"))) {
                    ValidateUtil.validNotNull(json, "goodsAmount", "goods Amount");
                }
            } else {
                throw new ApiException(ErrorCode.FIELD_FORMAT_ERR, "isInsure");
            }
        }
        // 版本号校验 add by changjun.xiang 2016-4-22
        if (json.containsKey("versionFlag")) {
            ValidateUtil.validNotNull(json, "versionFlag", "versionFlag");
            ValidateUtil.validMaxLength(json, "versionFlag", "versionFlag", 10);
        }
        // dispatchType
        ValidateUtil.validNotNull(json, "dispatchType", "Shipping Method");
        ValidateUtil.validMaxLength(json, "dispatchType", "Shipping Method", 1);
        // 派送方式为：S或P
        validDispatchType(json, "Shipping Method");
        // buyerName
        ValidateUtil.validNotNull(json, "buyerName", "Buyer Fullname");
        ValidateUtil.validMaxLength(json, "buyerName", "Buyer Fullname", 50);
        // buyerContactNo
        ValidateUtil.validNotNull(json, "buyerContactNo", "Buyer Phone Number");
        ValidateUtil.validMaxLength(json, "buyerContactNo", "Buyer Phone Number", 20);
        // buyerEmail
        ValidateUtil.validNotNull(json, "buyerEmail", "Buyer Email");
        ValidateUtil.validMaxLength(json, "buyerEmail", "Buyer Email", 60);
        ValidateUtil.validEmail(json, "buyerEmail", "Buyer Email");
        // buyerZipCode
        ValidateUtil.validNotNull(json, "buyerZipCode", "Buyer Zip");
        ValidateUtil.validMaxLength(json, "buyerZipCode", "Buyer Zip", 10);
        // buyerCountry
        ValidateUtil.validNotNull(json, "buyerCountry", "Buyer Country");
        ValidateUtil.validMaxLength(json, "buyerCountry", "Buyer Country", 50);
        // buyerState
        ValidateUtil.validNotNull(json, "buyerState", "Buyer State");
        ValidateUtil.validMaxLength(json, "buyerState", "Buyer State", 20);
        // buyerCity
        ValidateUtil.validNotNull(json, "buyerCity", "Buyer City");
        ValidateUtil.validMaxLength(json, "buyerCity", "Buyer City", 50);
        // buyerDistrict
        ValidateUtil.validMaxLength(json, "buyerDistrict", "Buyer District", 100);
        // buyerAddress1
        ValidateUtil.validNotNull(json, "buyerAddress1", "Buyer Address1");
        ValidateUtil.validMaxLength(json, "buyerAddress1", "Buyer Address1", 100);
        // buyerAddress2
        ValidateUtil.validMaxLength(json, "buyerAddress2", "Buyer Address2", 100);
        // buyerHouseNo
        ValidateUtil.validMaxLength(json, "buyerHouseNo", "House No.", 10);
        // buyerCitizenIdNumeber
        ValidateUtil.validMaxLength(json, "buyerCitizenIdNumber", "buyerCitizenIdNumeber", 32);
        // shipperAddrCode
        // ValidateUtil.validNotNull(json, "shipperAddrCode",
        // "Seller Address No.");
        ValidateUtil.validMaxLength(json, "shipperAddrCode", "Seller Address No.", 50);
        // currency
        ValidateUtil.validNotNull(json, "currency", "Currency");
        ValidateUtil.validMaxLength(json, "currency", "Currency", 10);
        // Total Amount
        ValidateUtil.validNotNull(json, "totalAmount", "Total Amount");
        ValidateUtil.validBigDecimal(json, "totalAmount", "Total Amount", true);
        // 保留两位小数
        rounding(json, "totalAmount", 2);
        ValidateUtil.validMaxLength(json, "totalAmount", "Total Amount", 10);

        /****************** expressNoList *******************/
        String dispatchType = (String) json.get("dispatchType");
        if (EceOrderDispatchType.SellerSend.getValue().equals(dispatchType)) {
            ValidateUtil.validNotNull(json, "expressNoList", "Express No.");
        }
        if (json.containsKey("expressNoList")) {
            JSONArray eNList = json.getJSONArray("expressNoList");
            for (Object object : eNList) {
                JSONObject expressNoJson = (JSONObject) object;
                if (expressNoJson.containsKey("expressNo")) {
                    ValidateUtil.validMaxLengthTrim(expressNoJson, "expressNo", "Express No.", 32);
                }
            }
        }

        /****************** orderPackageList *******************/
        // orderPackageList
        ValidateUtil.validNotNull(json, "orderPackageList");
        ValidateUtil.validList(json, "orderPackageList");

        JSONArray orderPackageList = json.getJSONArray("orderPackageList");
        for (Object obj : orderPackageList) {
            JSONObject orderLine = (JSONObject) obj;
            // grossWeight
            ValidateUtil.validNotNull(orderLine, "grossWeight", "Gross Weight");
            ValidateUtil.validBigDecimal(orderLine, "grossWeight", "Gross Weight", true);
            rounding(orderLine, "grossWeight", 2);
            ValidateUtil.validMaxLength(orderLine, "grossWeight", "Gross Weight", 10);
            numberTwo(orderLine.getBigDecimal("grossWeight"), "Gross Weight", 2);// 效验精度不能超过2

            /****************** merchandiseList *******************/
            ValidateUtil.validNotNull(orderLine, "merchandiseList");
            ValidateUtil.validList(orderLine, "merchandiseList");

            JSONArray merchandiseList = orderLine.getJSONArray("merchandiseList");
            for (Object object : merchandiseList) {
                JSONObject merchandise = (JSONObject) object;
                // productCode
                ValidateUtil.validNotNull(merchandise, "productCode", "Product Code");
                ValidateUtil.validMaxLength(merchandise, "productCode", "Product Code", 32);
                // productName
                ValidateUtil.validNotNull(merchandise, "productName", "Product Name");
                ValidateUtil.validMaxLength(merchandise, "productName", "Product Name", 255);
                /*
                 * 不需要规格查询商品 // specification
                 */
                /*
                 * ValidateUtil.validNotNull(merchandise, "specification",
                 * "Specification"); ValidateUtil.validMaxLength(merchandise,
                 * "specification", "Specification", 60);
                 */
                // quantity
                ValidateUtil.validNotNull(merchandise, "quantity", "Quantity");
                ValidateUtil.validMaxLength(merchandise, "quantity", "Quantity", 11);
                ValidateUtil.validInteger(merchandise, "quantity", "Quantity", true);
                // salePrice
                ValidateUtil.validNotNull(merchandise, "salePrice", "Sale Price");
                ValidateUtil.validBigDecimal(merchandise, "salePrice", "Sale Price", true);
                // 保留两位小数
                rounding(merchandise, "salePrice", 2);
                ValidateUtil.validMaxLengthTwo(merchandise, "salePrice", "Sale Price", 10);
                // currency
                ValidateUtil.validNotNull(merchandise, "currency", "Currency");
                ValidateUtil.validMaxLength(merchandise, "currency", "Currency", 10);
                // extraGift
                ValidateUtil.validNotNull(merchandise, "extraGift", "Extra Gift");
                ValidateUtil.validMaxLength(merchandise, "extraGift", "Extra Gift", 1);
                validExtraGift(merchandise, "Extra Gift");
                // brandName
                ValidateUtil.validNotNull(merchandise, "brandName", "Brand Name");
                ValidateUtil.validMaxLength(merchandise, "brandName", "Brand Name", 32);
            }
        }
    }

    /**
     * 进口订单保险字段校验
     * 
     * @param json
     */
    public static void validateInsuranceStatusField(JSONObject json) {
        ValidateUtil.valid(json, "orderNo", 32, true);
       // ValidateUtil.valid(json, "trackingNo", 32, true);
        ValidateUtil.valid(json, "messageCode", 20, true);
        ValidateUtil.valid(json, "userId", 20, true);
        ValidateUtil.valid(json, "extsequenceNo", 20, true);
       // ValidateUtil.valid(json, "projectNo", 20, true);
        ValidateUtil.valid(json, "Trade", 10, true);
        ValidateUtil.valid(json, "tranType", 10, true);
        ValidateUtil.validNotNull(json, "occurTime");
        ValidateUtil.validDateString(json, "occurTime", "yyyy-MM-dd HH:mm:ss");

    }

    /**
     * 兼容进口一期 校验进口订单
     * 
     * @param json
     */
    public static void validBatchImportOrder(JSONObject json) {

        // paymentTransactionID
        ValidateUtil.validNotNull(json, "paymentTransactionID");
        ValidateUtil.validMaxLength(json, "paymentTransactionID", 32);
        // refNo
        ValidateUtil.validMaxLength(json, "refNo", 60);
        // warehouseID
        ValidateUtil.validInteger(json, "warehouseID", true);
        ValidateUtil.validMaxLength(json, "warehouseID", 10);
        // winitProductCode
        ValidateUtil.validNotNull(json, "winitProductCode");
        ValidateUtil.validMaxLength(json, "winitProductCode", 50);
        // buyerName
        ValidateUtil.validNotNull(json, "buyerName");
        ValidateUtil.validMaxLength(json, "buyerName", 50);
        // buyerContactNo
        ValidateUtil.validNotNull(json, "buyerContactNo");
        ValidateUtil.validMaxLength(json, "buyerContactNo", 20);
        // buyerEmail
        ValidateUtil.validEmail(json, "buyerEmail");
        ValidateUtil.validMaxLength(json, "buyerEmail", 60);
        // buyerZipCode
        ValidateUtil.validNotNull(json, "buyerZipCode");
        ValidateUtil.validMaxLength(json, "buyerZipCode", 10);
        // buyerCountryCode
        ValidateUtil.validNotNull(json, "buyerCountryCode");
        ValidateUtil.validMaxLength(json, "buyerCountryCode", 50);
        // buyerState
        ValidateUtil.validNotNull(json, "buyerState");
        ValidateUtil.validMaxLength(json, "buyerState", 20);
        // buyerCity
        ValidateUtil.validNotNull(json, "buyerCity");
        ValidateUtil.validMaxLength(json, "buyerCity", 50);
        // buyerAddress1
        ValidateUtil.validNotNull(json, "buyerAddress1");
        ValidateUtil.validMaxLength(json, "buyerAddress1", 100);
        // buyerAddress2
        ValidateUtil.validMaxLength(json, "buyerAddress2", 100);
        // buyerHouseNo
        ValidateUtil.validMaxLength(json, "buyerHouseNo", 10);
        // buyerCitizenIdNumeber
        ValidateUtil.validMaxLength(json, "buyerCitizenIdNumeber", 32);
        // shipperAddrId
        ValidateUtil.validInteger(json, "shipperAddrId", "Buy Seller Address NO.");
        ValidateUtil.validMaxLength(json, "shipperAddrId", "Buy Seller Address NO.", 11);
        // CURRENCY
        ValidateUtil.validNotNull(json, "currency");
        // TOTALAMOUNT
        ValidateUtil.validBigDecimal(json, "totalAmount", true);
        /**
         * 如果shipperAddrId不为空，则校验shipperAddrId， 如果shipperAddrId为空，则校验发件人名字、
         * 发件人地址、发件人电话、发件人邮编、 发件人国家编码、发件人国家名称、发件 人州编码、发件人州名称、发件人城
         */
        if (json.containsKey("shipperAddrId")) {
            Object obj = json.get("shipperAddrId");
            if (null != obj) {
                // shipperAddrId
                ValidateUtil.validInteger(json, "shipperAddrId", true);
            } else {
                // shipperAddr
                ValidateUtil.validNotNull(json, "shipperAddr");
                ValidateUtil.validMaxLength(json, "shipperAddr", 100);
                // shipperName
                ValidateUtil.validNotNull(json, "shipperName");
                ValidateUtil.validMaxLength(json, "shipperName", 50);
                // shipperContactNo
                ValidateUtil.validNotNull(json, "shipperContactNo");
                ValidateUtil.validMaxLength(json, "shipperContactNo", 20);
                // shipperZipCode
                ValidateUtil.validNotNull(json, "shipperZipCode");
                ValidateUtil.validMaxLength(json, "shipperZipCode", 10);
                // shipperCountry
                ValidateUtil.validNotNull(json, "shipperCountry");
                ValidateUtil.validMaxLength(json, "shipperCountry", 50);
                // shipperCountryCode
                ValidateUtil.validNotNull(json, "shipperCountryCode");
                ValidateUtil.validMaxLength(json, "shipperCountryCode", 50);
                // shipperState
                ValidateUtil.validNotNull(json, "shipperState");
                ValidateUtil.validMaxLength(json, "shipperState", 20);
                // shipperStateCode
                ValidateUtil.validNotNull(json, "shipperStateCode");
                ValidateUtil.validMaxLength(json, "shipperStateCode", 20);
                // buyerCity
                ValidateUtil.validNotNull(json, "buyerCity");
                ValidateUtil.validMaxLength(json, "buyerCity", 50);
            }
        }
        // shipperEmail
        ValidateUtil.validEmail(json, "shipperEmail");
        ValidateUtil.validMaxLength(json, "shipperEmail", 60);

        /****************** expressNoList *******************/
        // expressNoList
        ValidateUtil.validList(json, "expressNoList");
        JSONArray expressNoList = json.getJSONArray("expressNoList");
        if (null != expressNoList && expressNoList.size() > 0) {
            for (Object object : expressNoList) {
                // 如果expressNoList不为空，则校验expressNo长度
                JSONObject expressNo = (JSONObject) object;
                ValidateUtil.validMaxLength(expressNo, "expressNo", 32);
            }
        }

        /****************** orderLineList *******************/
        // orderLineList
        ValidateUtil.validList(json, "orderLineList");
        ValidateUtil.validNotNull(json, "orderLineList");

        JSONArray orderLineList = json.getJSONArray("orderLineList");
        for (Object obj : orderLineList) {
            JSONObject orderLine = (JSONObject) obj;
            // grossWeight
            ValidateUtil.validBigDecimal(orderLine, "grossWeight", true);
            numberTwo(orderLine.getBigDecimal("grossWeight"), "grossWeight", 4);// 校验精度不能超过4
            // 包裹重量不得大于ApiConstant.ISP_IMPORT_GROSS_MAX
            if (ApiConstant.ISP_IMPORT_GROSS_MAX.compareTo(orderLine.getBigDecimal("grossWeight")) < 0) {
                throw new ApiException(ErrorCode.FIELD_DECIMAL_CANNOT_GREATER_THAN, new Object[] { "grossWeight",
                        ApiConstant.ISP_IMPORT_GROSS_MAX });
            }

            // merchandiseList
            ValidateUtil.validList(orderLine, "merchandiseList");
            ValidateUtil.validNotNull(orderLine, "merchandiseList");

            JSONArray merchandiseList = orderLine.getJSONArray("merchandiseList");
            for (Object object : merchandiseList) {
                JSONObject merchandise = (JSONObject) object;
                // productCode
                ValidateUtil.validNotNull(merchandise, "productCode");
                ValidateUtil.validMaxLength(merchandise, "productCode", 32);
                // specification
                ValidateUtil.validNotNull(merchandise, "specification");
                ValidateUtil.validMaxLength(merchandise, "specification", 60);
                // quantity
                ValidateUtil.validInteger(merchandise, "quantity", true);
                ValidateUtil.validMaxLength(merchandise, "quantity", 11);

                // salePrice
                ValidateUtil.validBigDecimal(merchandise, "salePrice", true);
                numberTwo(merchandise.getBigDecimal("salePrice"), "salePrice", 2);// 校验精度不能超过2
                // 包裹总价值不得大于ApiConstant.ISP_IMPORT_GROSS_MAX
                if (ApiConstant.ISP_IMPORT_SALE_PRICE.compareTo(merchandise.getBigDecimal("salePrice")) < 0) {
                    throw new ApiException(ErrorCode.FIELD_DECIMAL_CANNOT_GREATER_THAN, new Object[] { "salePrice",
                            ApiConstant.ISP_IMPORT_SALE_PRICE });
                }

                // currency
                ValidateUtil.validNotNull(merchandise, "currency");
                ValidateUtil.validMaxLength(merchandise, "currency", 10);
                // extraGift
                ValidateUtil.validNotNull(merchandise, "extraGift");
                ValidateUtil.validMaxLength(merchandise, "extraGift", 1);
                // brandName
                ValidateUtil.validNotNull(merchandise, "brandName");
                ValidateUtil.validMaxLength(merchandise, "brandName", 32);
            }
        }
    }

    /**
     * TODO 校验订单（update
     * 
     * @param json
     */
    public static void validOrderNoField(JSONObject json) {
        ValidateUtil.validNotNull(json, "orderNo");
        ValidateUtil.validMaxLength(json, "orderNo", 60);
    }

    /**
     * 限制"发货方式"必须为S/P
     * 
     * @param json
     */
    public static void validDispatchType(JSONObject json, String key) {
        String dispatchType = (String) json.get("dispatchType");
        if (!EceOrderDispatchType.SellerSend.getValue().equals(dispatchType)
            && !EceOrderDispatchType.WinitPickup.getValue().equals(dispatchType)) {
            throw new ApiException(ErrorCode.FIELD_VALUE_NOT_EXISIT, key, dispatchType);
        }
    }

    /**
     * 限制"是否为赠品"的值为Y/N
     * 
     * @param json
     * @param key
     */
    public static void validExtraGift(JSONObject json, String key) {
        String extraGift = (String) json.get("extraGift");
        if (!"Y".equals(extraGift) && !"N".equals(extraGift)) {
            throw new ApiException(ErrorCode.FIELD_VALUE_NOT_EXISIT, key, extraGift);
        }
    }

    /**
     * 校验BigDecimal精确位数
     * 
     * @param big
     * @param key
     * @param value
     */
    public static void numberTwo(BigDecimal big, String key, int value) {
        if (big.scale() > value) {
            throw new ApiException(ErrorCode.FIELD_FAILED_NOT_TWO, key, value);
        }
    }

    private static void rounding(JSONObject json, String key, int scale) {
        BigDecimal decimalValue = json.getBigDecimal(key).setScale(scale, BigDecimal.ROUND_HALF_UP);
        json.put(key, decimalValue.toString());
    }
}
